/***************************************************************************
 * Copyright 2012-2013 TXT e-solutions SpA
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the contract ICT-257367.
 *
 * Authors:
 *      Salvatore Piccione (TXT e-solutions SpA)
 *
 * Contributors:
 *        Domenico Rotondi (TXT e-solutions SpA)
 **************************************************************************/
package it.txt.ens.core.impl;

import it.txt.ens.core.ENSResource;
import it.txt.ens.core.factory.ENSResourceFactory;
import it.txt.ens.core.factory.URIBuildingException;
import it.txt.ens.core.factory.URIParseException;
import it.txt.ens.core.util.parser.ENSResourceURIParser;

import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.client.utils.URIBuilder;

/**
 * This class provides the default implementation of {@link ENSResource}.
 * 
 * @author Salvatore Piccione (TXT e-solutions SpA - salvatore.piccione AT txtgroup.com)
 * @author Domenico Rotondi (TXT e-solutions SpA - domenico.rotondi AT txtgroup.com)
 *
 */
public class BasicENSResource implements ENSResource {
    
    private final String host;
    private final String namespace;
    private final String path;
    private final String pattern;
    private final URI uri;
    
    //I don't use the Builder pattern because all fields are mandatory and only 'path' has a default value
//   
//    private BasicENSResource (String host, String path, String namespace, String pattern, URI uri) {
//        this.host = host;
//        this.path = path;
//        this.namespace = namespace;
//        this.pattern = pattern;
//        this.uri = uri;
//    }
    
    /**
     * 
     * @param host
     * @param namespace
     * @param pattern
     * @throws IllegalArgumentException if at least one parameter is <code>null</code> or an empty string.
     * @throws URIBuildingException if an error occurs while building the URI
     */
    /*private*/ BasicENSResource (String host, String namespace, String pattern) throws IllegalArgumentException, URIBuildingException{
        this(host,DEFAULT_PATH,namespace,pattern);
    }
    
    /**
     * 
     * @param host
     * @param path
     * @param namespace
     * @param pattern
     * @throws IllegalArgumentException if at least one parameter is <code>null</code> or an empty string.
     * @throws URIBuildingException if an error occurs while building the URI
     */
    /*private*/ BasicENSResource (String host, String path, String namespace, String pattern) throws IllegalArgumentException, URIBuildingException{
        if (host == null)
            throw new IllegalArgumentException("The host cannot be null");
        if (host.length() == 0)
            throw new IllegalArgumentException("The host cannot be an empty string");
        
        if (path == null)
            throw new IllegalArgumentException ("The path cannot be null");
        if (path.length() == 0)
            throw new IllegalArgumentException ("The path cannot be an empty string");
        
        if (namespace == null)
            throw new IllegalArgumentException ("The namespace cannot be null");
        if (namespace.length() == 0)
            throw new IllegalArgumentException ("The namespace cannot be an empty string");
        
        if (pattern == null)
            throw new IllegalArgumentException ("The pattern cannot be null");
        if (pattern.length() == 0)
            throw new IllegalArgumentException ("The pattern cannot be an empty string");
        this.host = host;
        this.namespace = namespace;
        if (path.startsWith(SLASH))
            this.path = path;
        else
            this.path = SLASH + path;
        this.pattern = pattern;
        URIBuilder uriBuilder = new URIBuilder();
        uriBuilder.addParameter(NAMESPACE_PARAMETER_NAME, this.namespace);
        uriBuilder.addParameter(PATTERN_PARAMETER_NAME, this.pattern);
        uriBuilder.setHost(this.host);
        uriBuilder.setPath(this.path);
        uriBuilder.setScheme(URI_SCHEME);
        try {
            this.uri = uriBuilder.build();
        } catch (URISyntaxException e) {
            throw new URIBuildingException ("getURI.URISyntaxException.log",e);
        }
    }

    /* (non-Javadoc)
     * @see it.txt.ens.core.ENSResource#getHost()
     */
    public String getHost() {
        return host;
    }

    /* (non-Javadoc)
     * @see it.txt.ens.core.ENSResource#getPath()
     */
    public String getPath() {
        return path;
    }

    /* (non-Javadoc)
     * @see it.txt.ens.core.ENSResource#getNamespace()
     */
    public String getNamespace() {
        return namespace;
    }

    /* (non-Javadoc)
     * @see it.txt.ens.core.ENSResource#getPattern()
     */
    public String getPattern() {
        return pattern;
    }

    /* (non-Javadoc)
     * @see it.txt.ens.core.ENSResource#getURI()
     */
    public URI getURI() {
        return uri;
    }
        
    public static class BasicENSResourceFactory implements ENSResourceFactory {

        /* (non-Javadoc)
         * @see it.txt.ens.core.factory.ENSResourceFactory#create(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
         */
        @Override
        public synchronized ENSResource create(String host, String path, String namespace,
                String pattern) throws IllegalArgumentException,
                URIBuildingException {
            return new BasicENSResource(host, path, namespace, pattern);
        }

        /* (non-Javadoc)
         * @see it.txt.ens.core.factory.ENSResourceFactory#create(java.lang.String, java.lang.String, java.lang.String)
         */
        @Override
        public synchronized ENSResource create(String host, String namespace, String pattern)
                throws IllegalArgumentException, URIBuildingException {
            return new BasicENSResource(host, namespace, pattern);
        }

        /* (non-Javadoc)
         * @see it.txt.ens.core.factory.ENSResourceFactory#create(java.net.URI)
         */
        @Override
        public synchronized ENSResource create(java.net.URI uri)
                throws IllegalArgumentException, URIParseException {
            return ENSResourceURIParser.parse(uri,this);
        }
        
    }
    

    public static void main (String[] args) {
        try {
            ENSResource r = ENSResourceURIParser.parse(
                    new URI("amqp://www.iot-at-work.eu/ENS?Namespace=Demo+IoTatWork+Namespace&Pattern=DemoIoTatWork.Turin.CRFPlant.WeldingCell1.%23.Energy"),
                    new BasicENSResourceFactory());
            System.out.println(r.getPattern());
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (URIParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
